import re

from django_redis import get_redis_connection

from .models import *
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings


class UserCreateSerializer(serializers.Serializer):
    """定义序列器的属性"""
    # 增加token字段
    token = serializers.CharField(read_only=True)
    id = serializers.IntegerField(read_only=True)
    username = serializers.CharField(
        max_length=20,
        min_length=5,
        error_messages={
            "max_length": "用户名需为5-20个字符",
            "min_length": "用户名需为5-20个字符",
        }
    )
    password = serializers.CharField(
        min_length=8,
        max_length=20,
        error_messages={
            "max_length": "密码需为8-20个字符",
            "min_length": "密码需为8-20个字符",
        },
        write_only=True  # 只接收客户端数据
    )
    password2 = serializers.CharField(
        min_length=8,
        max_length=20,
        error_messages={
            "max_length": "密码需为8-20个字符",
            "min_length": "密码需为8-20个字符",
        },
        write_only=True
    )
    sms_code = serializers.IntegerField(write_only=True)
    mobile = serializers.CharField()
    allow = serializers.CharField(write_only=True)

    """ 验证接收的属性是否合法 """
    def validate_username(self,value):
        """验证用户"""
        print('1')
        count = User.objects.filter(username = value).count()
        if count:
            raise serializers.ValidationError('用户名已经存在')
        return value

    def validate_mobile(self,value):
        """验证手机"""
        print('2')

        if not re.match(r'^1[3-9]\d{9}$',value):
            raise serializers.ValidationError('手机号格式错误')

        count = User.objects.filter(mobile = value).count()
        if count:
            raise serializers.ValidationError('该手机已经注册')

        return value

    def validate_allow(self,value):
        """验证协议是否勾选"""
        print('3')

        if not value:
            raise serializers.ValidationError('请阅读并同意使用协议')
        return value

    """多属性检查"""
    def validate(self, attrs):
        print('4')

        """校验密码是否一致"""
        password = attrs.get('password')
        password2 = attrs.get('password2')
        if password != password2:
            raise serializers.ValidationError('两次输入的密码不一致')

        """校验验证码是否正确"""
        sms_code_request = attrs.get('sms_code')
        mobile = attrs.get('mobile')
        # 获取redis中的验证码
        redis_cli = get_redis_connection('sms_code')
        sms_code_redis = redis_cli.get('sms_code_'+mobile)
        # 如未查询到
        if sms_code_redis is None:
            raise serializers.ValidationError('验证码以失效')
        # 强行让验证码过期
        redis_cli.delete("sms_code_" + mobile)

        # 如验证码不正确
        """特别注意:redis查出来的对象是byte形式,需转化后进行对比"""
        if int(sms_code_request) != int(sms_code_redis):
            raise serializers.ValidationError("验证码输入错误")

        return attrs

    """保存"""
    def create(self, validated_data):
        print('5')

        user = User()
        user.username = validated_data.get('username')
        user.mobile = validated_data.get('mobile')
        # 对密码进行加密
        user.set_password(validated_data.get('password'))
        user.save()

        # 需要生成token
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        user.token = token # 创建token字段

        return user

